#include "tm1638.h"

const uint8_t tab[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00};

uint8_t dot = 0x00;

uint8_t wipe = 0;

void STB(uint8_t status) {
  HAL_GPIO_WritePin(STB_GPIO_Port, STB_Pin, status > 0 ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

void CLK(uint8_t status) {
  HAL_GPIO_WritePin(CLK_GPIO_Port, CLK_Pin, status > 0 ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

void DIO(uint8_t status) {
  HAL_GPIO_WritePin(DIO_GPIO_Port, DIO_Pin, status > 0 ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

//写数据
void tm1638_Write(uint8_t DATA) {
  uint8_t i;

  for (i = 0; i < 8; i++) {
    CLK(0);

    if (DATA & 0X01) {
      DIO(1);
    } else {
      DIO(0);
    }

    CLK(1);

    DATA >>= 1;
  }
}

//读数据
uint8_t TM1638_Read(void) {
	uint8_t i;
	uint8_t temp=0;
	
	DIO(1);
	
	for(i=0;i<8;i++){
		temp >>= 1;
		
		CLK(0);
		if(HAL_GPIO_ReadPin(DIO_GPIO_Port, DIO_Pin)){
			temp |= 0x80;
		}
		CLK(1);
	}
	
	return temp;
}

uint8_t Read_key(void){
	uint8_t c[4], i, key_value=0;
	
	STB(0);
	
	tm1638_Write(0x42);
	
	for(i=0;i<4;i++){
		c[i]=TM1638_Read();
	}	
		
	STB(1);
	
	for(i=0;i<4;i++){
		key_value |= c[i]<<i;
	}
		
	for(i=0;i<8;i++){
		if((0x01<<i)==key_value)
			break;
	}
		
	return i;
}

//发送命令字
void Write_COM(uint8_t cmd) {
  STB(0);
  tm1638_Write(cmd);
  STB(1);
}

//指定地址写入数据
void Write_DATA(uint8_t index, uint8_t DATA) {
  Write_COM(DATA_COMMAND | 0x04);

  STB(0);
  tm1638_Write(ADDR_COMMAND | (index << 1));
  tm1638_Write(DATA);
  STB(1);
}

void clear() {
  uint8_t i = 0;

  Write_COM(0x40);

  STB(0);

  tm1638_Write(ADDR_COMMAND);
  for (i = 0; i < 16; i++) {
    tm1638_Write(0x00);
  }

  STB(1);
}

void show_num(uint16_t num1, uint16_t num2) {
	if(num1 == 0xffff || num2 == 0xffff) {
		clear();
	}
	
	if(num1 != 0xffff) {
		Write_DATA(0, tab[num1 / 1000 % 10] | dot);
		Write_DATA(1, tab[num1 / 100 % 10] | dot);
		Write_DATA(2, tab[num1 / 10 % 10] | dot);
		Write_DATA(3, tab[num1 % 10] | dot);
	}
	
	if(num2 != 0xffff) {		
		Write_DATA(4, tab[num2 / 1000 % 10] | dot);
		Write_DATA(5, tab[num2 / 100 % 10] | dot);
		Write_DATA(6, tab[num2 / 10 % 10] | dot);
		Write_DATA(7, tab[num2 % 10] | dot);
	}
}

void show_dot(uint8_t on) {
	if(on) {
		dot = 0x80;
	} else {
		dot = 0x00;
	}
}

void tm1638_init(void) {
  //设置最高亮度
  Write_COM(DISP_COMMAND | 0x0f);

  clear();
}
